var http = require('http')
var crypto = require('crypto')
var request = require('request')
import CONFIG from '../config'
import ffmpeg from 'ffmpeg'
import COS from 'cos-nodejs-sdk-v5'
import * as helper from '../lib/helper'
import fs from 'fs'
import gifify from 'gifify'
import path from 'path'

var config = CONFIG.cos

const cos = new COS({
  SecretId: config.SecretId,
  SecretKey: config.SecretKey,
})

var util = {
  // 获取随机数
  getRandom: function(min, max) {
    return Math.round(Math.random() * (max - min) + min)
  },
  // obj 转 query string
  json2str: function(obj) {
    var arr = []
    Object.keys(obj)
      .sort()
      .forEach(function(item) {
        var val = obj[item] || ''
        arr.push(item + '=' + val)
      })
    return arr.join('&')
  },
  // 计算签名
  getSignature: function(opt, key, method) {
    var formatString =
      method + config.Domain + '/v2/index.php?' + util.json2str(opt)
    var hmac = crypto.createHmac('sha1', key)
    var sign = hmac.update(new Buffer(formatString, 'utf8')).digest('base64')
    return sign
  }
}

// 拼接获取临时密钥的参数
export const getTempKeys = function(callback) {
  // 判断是否修改了 AllowPrefix
  if (config.AllowPrefix === '_ALLOW_DIR_/*') {
    callback({ error: '请修改 AllowPrefix 配置项，指定允许上传的路径前缀' })
    return
  }

  // 定义绑定临时密钥的权限策略
  var ShortBucketName = config.Bucket.substr(0, config.Bucket.lastIndexOf('-'))
  var AppId = config.Bucket.substr(1 + config.Bucket.lastIndexOf('-'))
  var policy = {
    version: '2.0',
    statement: [
      {
        action: ['name/cos:*'],
        effect: 'allow',
        principal: { qcs: ['*'] },
        resource: [
          'qcs::cos:' +
            config.Region +
            ':uid/' +
            AppId +
            ':prefix//' +
            AppId +
            '/' +
            ShortBucketName +
            '/',
          'qcs::cos:' +
            config.Region +
            ':uid/' +
            AppId +
            ':prefix//' +
            AppId +
            '/' +
            ShortBucketName +
            '/' +
            config.AllowPrefix
        ]
      }
    ]
  }

  var policyStr = JSON.stringify(policy)

  var Action = 'GetFederationToken'
  var Nonce = util.getRandom(10000, 20000)
  var Timestamp = parseInt(+new Date() / 1000)
  var Method = 'GET'

  var params = {
    Action: Action,
    Nonce: Nonce,
    Region: '',
    SecretId: config.SecretId,
    Timestamp: Timestamp,
    durationSeconds: 7200,
    name: '',
    policy: policyStr
  }
  params.Signature = encodeURIComponent(
    util.getSignature(params, config.SecretKey, Method)
  )

  var opt = {
    method: Method,
    url: config.Url + '?' + util.json2str(params),
    rejectUnauthorized: false,
    headers: {
      Host: config.Domain
    },
    proxy: config.Proxy || ''
  }
  request(opt, function(err, response, body) {
    body = body && JSON.parse(body)
    if (body.data) body = body.data
    callback(err, body)
  })
}

/**
 * 为视频cos资源生成封面图，需要本地创建临时处理路径(默认tmp-video)，并赋予可读写权限
 * @param  {[type]}  key [description]
 * @return {Promise}     [description]
 */
export const genVideoCoverPic = async (key, tmpDir = '/tmp-video') => {
  let tmpKey = helper.md5(key)

  let tmpPath = `${tmpDir}/${tmpKey}`
  let successPath = `${tmpDir}/success-${tmpKey}`
  let successGifPath = `${tmpDir}/success-gif-${tmpKey}`

  // 把cos资源下载到本地
  await getObject({key, output: tmpPath})

  // 对cos资源截图处理
  let rs = null
  try {
    rs = await new Promise((resolve, reject) => {
      let process = new ffmpeg(tmpPath)
      process.then((video) => {
        video.fnExtractFrameToJPG(tmpDir + '/', {
          frame_rate: 1,
          number: 1,
          keep_pixel_aspect_ratio: true,
          keep_aspect_ratio: true,
          padding_color: 'black',
          file_name: successPath
        }, (error, files) => {
          if (error) reject(error)
          resolve(files)
        })
      }, (err) => {
        reject(err)
      })
    })
  } catch (e) {
    // 删除缓存资源
    fs.unlinkSync(tmpPath)
    fs.unlinkSync(successPath)
    throw e
  }

  // 把截图结果上传到cos
  let coverPicKey = 'materials/pics/' + helper.genNo()
  successPath += '_1.jpg'
  await putObject({key: coverPicKey, filepath: successPath})

  // 删除缓存资源
  fs.unlinkSync(tmpPath)
  // fs.unlinkSync(successPath)

  return coverPicKey
}

export const getObject = async ({key, bucket = config.Bucket, region = config.Region, output = ''}) => {
  let opts = {Key: key, Bucket: bucket, Region: region}
  if (output) {
    opts.Output = output
  }
  let rs = await new Promise((resolve, reject) => {
    cos.getObject(opts, (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
  return rs
}

export const putObject = async ({key, filepath, bucket = config.Bucket, region = config.Region}) => {
  let rs = new Promise((resolve, reject) => {
    cos.putObject({
      Bucket: bucket,
      Region: region,
      Key: key,
      Body: fs.createReadStream(filepath),
      ContentLength: fs.statSync(filepath).size
    }, (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
  return rs
}
